package org.rooster.dbmanager.repository;

import org.rooster.dbmanager.datasource.DataSource;
import org.rooster.schedule.*;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: manorama
 * Date: 7/29/12
 * Time: 12:37 PM
 * To change this template use File | Settings | File Templates.
 */
public class RoosterRepository {

    private static DataSource roosterDataSource;
    private static RoosterRepository instance;

    /**
     * To implement singleton pattern the constructor is made private
     * @param dataSource
     */
    private RoosterRepository(DataSource dataSource) {
        RoosterRepository.roosterDataSource = dataSource;
    }

    /**
     * get the corresponding database data source
     * @param 
     * returns DataSource
     */
    private static DataSource getDataSource() {

        RoosterDataSourceFactory dataSourceFactory = new RoosterDataSourceFactory();
        return dataSourceFactory.getDataSource();
    }

    /**
     *
     * @return the static instance of Rooster Repository
     */
    public static RoosterRepository getInstance() {

        if (instance == null) {

            instance = new RoosterRepository(getDataSource());

        }
        return instance;
    }

    /**
     * insert a resource requirement record to the database
     * @param resourceRequirement
     */
    public void insertResourceRequirement(ResourceRequirement resourceRequirement) {
        try {
            try {
                roosterDataSource.insertResourceRequirement(resourceRequirement);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * Retrieve the resource requirements for all the tasks
     * @return
     */
    public Set retrieveResourceRequirementsForSchedule() {
        try {
            try {
                return roosterDataSource.retrieveResourceRequirementsForSchedule();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Retrieves the resource requirement for a particular task
     *
     * @param taskNo
     * @return
     */
    public List getTaskRequirement(int taskNo) {
        try {
            try {
                return roosterDataSource.getTaskRequirement(taskNo);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * retrieve all the resource allocations for the schedule
     * @return
     */
    public Set getScheduleResourceAllocations() {
        try {
            try {
                return roosterDataSource.getScheduleResourceAllocations();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * inserts a record of resource allocation
     * @param resourceAllocation
     */
    public void insertResourceAllocation(ResourceAllocation resourceAllocation) {
        try {
            try {
                roosterDataSource.insertResourceAllocation(resourceAllocation);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     */
    public void clearScheduleTable() {
        try {
            try {
                roosterDataSource.clearScheduleTable();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * return the resource details as a resource object
     * @param resourceID
     * @return
     */
    public Resource getResourceRecord(int resourceID) {
        try {
            return roosterDataSource.getResourceRecord(resourceID);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * return the set of available resources
     * @return
     */
    public Set getAvailableResources() {
        try {
            return roosterDataSource.getAvailableResources();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @return
     * @throws UnknownHostException
     */
    public int getTotalResourceCount() throws UnknownHostException {
        try {
            return roosterDataSource.getTotalResourceCount();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 
     * @param resourceCapability
     */
    public void insertResourceCapability(ResourceCapability resourceCapability) {
        try {
            try {
                roosterDataSource.insertResourceCapability(resourceCapability);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @return
     */
    public Set<ResourceCapability> getResourceCapabilities() {
        try {
            try {
                return roosterDataSource.getResourceCapabilities();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param managerPreference
     */
    public void insertManagerPreference(ManagerPreference managerPreference) {
        try {
            try {
                roosterDataSource.insertManagerPreference(managerPreference);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @return
     */
    public Set<ManagerPreference> retrieveManagerPreferencesSet() {
        try {
            try {
                return roosterDataSource.getManagerPreferencesSet();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param resourcePreference
     */
    public void insertResourcePreference(ResourcePreference resourcePreference) {
        try {
            try {
                roosterDataSource.insertResourcePreferenceRecord(resourcePreference);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @return
     */
    public Set<ResourcePreference> retrieveResourcePreferencesSet() {
        try {
            try {
                return roosterDataSource.getResourcePreferenceSet();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @return
     */
    public Set<Resource> getAllResources() {
        try {
            try {
                return roosterDataSource.getAllResources();
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param resourceId
     * @param availability
     */
    public void serResourceAvailability(int resourceId, int availability) {
        try {
            try {
                roosterDataSource.setResourceAvailability(resourceId, availability);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param searchString
     * @return
     */
    public Set<Resource> searchResourcesByName(String searchString) {
        try {
            try {
                return roosterDataSource.searchResourcesByName(searchString);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param resourceId
     * @return
     */
    public Set<ResourcePreference> retrievePreferencesForResource(int resourceId) {
        try {
            try {
                return roosterDataSource.retrievePreferencesForResource(resourceId);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param resource
     * @param previousResourceId
     */
    public void updateResourceDetails(Resource resource, int previousResourceId) {
        try {
            try {
                roosterDataSource.updateResourceDetails(resource, previousResourceId);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param resourceId
     * @param file
     * @throws FileNotFoundException
     */
    public void saveResourceImage(int resourceId, File file) throws FileNotFoundException {
        try {
            try {
                roosterDataSource.saveResourceImage(resourceId, file);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param resourcePreference
     */
    public void updateResourcePreference(ResourcePreference resourcePreference) {
        try {
            try {
                roosterDataSource.updateResourcePreference(resourcePreference);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param taskId
     * @return
     */
    public Task getTaskById(int taskId) {
        try {
            return roosterDataSource.getTaskById(taskId);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param id
     * @return
     */
    public TimeSlot getTimeSlotById(int id) {
        try {
            return roosterDataSource.getTimeSlotById(id);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     * @param resourceCapability
     */
    public void updateResourceCapability(ResourceCapability resourceCapability) {
        try {
            try {
                roosterDataSource.updateResourceCapability(resourceCapability);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param managerPreference
     */
    public void updateManagerPreference(ManagerPreference managerPreference) {
        try {
            try {
                roosterDataSource.updateManagerPreference(managerPreference);
            } catch (UnknownHostException ex) {
                Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @return
     */
    public Set<ResourceType> getResourceTypes() {
        try {
            return roosterDataSource.getResourceTypes();
        } catch (SQLException ex) {
            Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnknownHostException ex) {
            Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * 
     * @param resourceTypeId
     * @return
     */
    public Set<Resource> getResourcesByResourceType(int resourceTypeId) {
        try {
            return roosterDataSource.getResourcesByResourceType(resourceTypeId);
        } catch (SQLException ex) {
            Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnknownHostException ex) {
            Logger.getLogger(RoosterRepository.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}
